package backtrace;

/**
 * N皇后问题
 *
 * @author zj
 */
public class NQueen {
    public static void main(String[] args) {
        find(8);
    }

    public static void find(int n) {
        int count = 0; //统计找到解的个数
        int c[] = new int[n + 1]; //c[i] = j 表示摆放在第i行第j列
        for (int k = 0; k < c.length; k++) {
            c[k] = 0;
        }
        int k = 1;
        while (k >= 1) {
            boolean f = true;
            while (c[k] < n) {
                c[k] = c[k] + 1;
                if (isCorrect(c, k)) { //如果k号皇后摆放位置合法
                    //如果这是最后一个皇后，即全部摆放好了，输出本次结果
                    if (k == n) {
                        count++;
                        print(c, count);
                    } else {  //还未摆完
                        k++;  //前进，继续摆下一个皇后
                        f = false;  //此处的f标志用来控制在退出内层循环后是否要回溯
                        break;
                    }
                }
            }
            if (f) {  //回溯
                c[k] = 0;
                k--;
            }
        }

    }

    /**
     * 判断摆放k号皇后以后，它和前面已摆好的皇后会不会相互攻击
     *
     * @param c
     * @param k
     * @return
     */
    private static boolean isCorrect(int c[], int k) {
        for (int i = 1; i < k; i++) {
            if (c[i] == c[k] || (c[i] - c[k]) == (i - k)
                    || (c[k] - c[i]) == (i - k)) {
                return false;
            }
        }
        return true;
    }

    private static void print(int c[], int count) {
        if (c == null || count == 0) {
            System.out.println("无解");
        } else {
            System.out.print("第【" + count + "】个解：");
            for (int i = 1; i < c.length; i++) {
                System.out.print(c[i] + " ");
            }
            System.out.println();
        }
    }
}
